package layers.ants;

import layers.agents.PackageAgent;
import layers.physical.Crossroad;
import layers.physical.Road;

public class PackageAnt extends Ant {

	private final long AMOUNT_OF_PHEROMONES = 500*1000;
	private long distanceTraveled;
	private Road roadTraveled;

	public PackageAnt(Crossroad crossroad, long distanceTraveled, Road roadTraveled, PackageAgent agent) {
		super(crossroad, agent);
		if(agent == null)
			throw new IllegalArgumentException("Package agent cannot be null.");
		if(distanceTraveled < 0)
			throw new IllegalArgumentException("Distance traveled must be positive.");
		this.setAgent(agent);
		this.distanceTraveled = distanceTraveled;
		this.roadTraveled = roadTraveled;
	}

	@Override
	public void processAntTick() {
		if(!this.getCrossroad().hasMoreOrEqualAmountOfPheromonesThen(this.getPheromoneCount())){
			this.dropPheromones();
			for(Road road : this.getCrossroad().getIncomingConnections())
				if(hasSufficientPheromones(road) && !equalsRoadLastTraveled(road))
					clonePackageAnt(road);
		}
		this.die();
	}

	private boolean hasSufficientPheromones(Road road) {
		return this.AMOUNT_OF_PHEROMONES - (road.getLength() + distanceTraveled) > 1;
	}

	private boolean equalsRoadLastTraveled(Road road) {
		boolean result = this.roadTraveled == road;
		return result;
	}

	private void clonePackageAnt(Road road) {
		Crossroad nextCrossroad = road.getOtherConnector(this.getCrossroad());
		new PackageAnt(nextCrossroad, this.getDistanceTraveled() + road.getLength(), road, (PackageAgent) this.getAgent());
	}

	private long getDistanceTraveled() {
		return this.distanceTraveled;
	}

	private long getPheromoneCount(){
		return (Math.max(AMOUNT_OF_PHEROMONES - distanceTraveled,0));
	}

	private void dropPheromones(){
		long pheromones = this.AMOUNT_OF_PHEROMONES - distanceTraveled;
		this.getCrossroad().dropPackageAntPheromones(this.roadTraveled, pheromones);
	}
}
